-module(face).
-export([hittest/2, get_material/2]).
-export([new/0, new/5]).
-export([get_mtlid/1, set_mtlid/2]).
-export([get_normal/1, set_normal/2]).
-export([get_vertices/1, set_vertices/2]).
-export([surface/1]).

-record(face, {
        mtlid=0,
        a={},   %vertex 1
        b={},   %vertex 2
        c={},   %vertex 3
        n={}   %face normal
      }).

surface(#face{a=A, b=B, c=C}) ->
    AB = vector:dif(A, B),
    BC = vector:dif(C, B),
    vector:length(vector:xprod(AB, BC))*0.5.

hittest(Ray, Face) ->
    A = Face#face.a,
    B = Face#face.b,
    C = Face#face.c,

    {RayPosition, RayDirection} = ray:split(Ray),

    Edge1 = vector:dif(B, A),
    Edge2 = vector:dif(C, A),

    Pvec = vector:xprod(RayDirection, Edge2),
    Det = vector:dprod(Edge1, Pvec),

    case Det*Det > 0.001 of
        true ->
            InvDet = 1/Det,
            Tvec = vector:dif(RayPosition, A),
            U = vector:dprod(Tvec, Pvec)*InvDet,
            case U < 0 orelse U > 1 of
                true -> false;
                false ->
                    Qvec = vector:xprod(Tvec, Edge1),
                    V = vector:dprod(RayDirection, Qvec)*InvDet,
                    Test2 = V < 0 orelse (U+V) > 1,
                    case Test2 of
                        true -> false;
                        false ->
                            HitDistance = vector:dprod(Edge2, Qvec)*InvDet,
                            {HitDistance, Face, {U, V}}
                    end
            end;
        false -> false
    end.

get_material(Face, Scene) ->
    MtlID = get_mtlid(Face),
    hd(lists:filter(fun(M) -> material:get_id(M) == MtlID end, scene:get_materials(Scene))).

new() -> #face{}.
new(MtlID, A, B, C, N) -> #face{mtlid=MtlID, a=A, b=B, c=C, n=N}.

get_mtlid(Face) -> Face#face.mtlid.
set_mtlid(MtlID, Face) -> Face#face{mtlid=MtlID}.

get_normal(Face) -> Face#face.n.
set_normal(N, Face) -> Face#face{n=N}.

get_vertices(Face) -> {Face#face.a, Face#face.b, Face#face.c}.
set_vertices({A, B, C}, Face) -> Face#face{a=A, b=B, c=C}.